package com.telchina.workorder.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.telchina.common.core.domain.AjaxResult;
import com.telchina.common.core.domain.entity.SysOrg;
import com.telchina.common.enums.ConsStatusEnum;
import com.telchina.common.enums.ReplyTypeEnum;
import com.telchina.utils.CalculateUtil;
import com.telchina.workorder.domain.WoDisregardKpi;
import com.telchina.workorder.domain.WoExtension;
import com.telchina.workorder.domain.WoSupervise;
import com.telchina.workorder.domain.WoWorkOrder;
import com.telchina.workorder.domain.vo.analysis.WoComparisonResVO;
import com.telchina.workorder.domain.vo.analysis.WoSatisfactionResVO;
import com.telchina.workorder.domain.vo.analysis.WoStatisticAnalysisReqVO;
import com.telchina.workorder.domain.vo.analysis.WoThroughputResVO;
import com.telchina.workorder.mapper.WoDisregardKpiMapper;
import com.telchina.workorder.mapper.WoExtensionMapper;
import com.telchina.workorder.mapper.WoSuperviseMapper;
import com.telchina.workorder.mapper.WoWorkOrderMapper;
import com.telchina.workorder.service.IWoStatisticAnalysisService;
import com.telchina.workorder.third.service.SystemThirdService;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class WoStatisticAnalysisServiceImpl implements IWoStatisticAnalysisService {

    @Resource
    private WoWorkOrderMapper woWorkOrderMapper;
    @Resource
    private SystemThirdService systemThirdService;
    @Resource
    private WoExtensionMapper woExtensionMapper;
    @Resource
    private WoSuperviseMapper woSuperviseMapper;
    @Resource
    private WoDisregardKpiMapper woDisregardKpiMapper;

    /**
     * 工单统计
     *
     * @param woStatisticAnalysisReqVO
     * @return
     */
    @Override
    public AjaxResult throughput(WoStatisticAnalysisReqVO woStatisticAnalysisReqVO) {
        woStatisticAnalysisReqVO.setDimension("dispatchTime");

        List<WoWorkOrder> source = findSource(woStatisticAnalysisReqVO); // 本期数据
        WoStatisticAnalysisReqVO statisticAnalysisReqVOYOY = BeanUtil.copyProperties(woStatisticAnalysisReqVO, WoStatisticAnalysisReqVO.class);
        statisticAnalysisReqVOYOY.setStartDate(DateUtil.offset(woStatisticAnalysisReqVO.getStartDate(), DateField.YEAR, -1));
        statisticAnalysisReqVOYOY.setEndDate(DateUtil.offset(woStatisticAnalysisReqVO.getEndDate(), DateField.YEAR, -1));
        List<WoWorkOrder> sourceYOY = findSource(statisticAnalysisReqVOYOY); // 同比数据
        WoStatisticAnalysisReqVO statisticAnalysisReqVOMOM = BeanUtil.copyProperties(woStatisticAnalysisReqVO, WoStatisticAnalysisReqVO.class);
        statisticAnalysisReqVOMOM.setStartDate(DateUtil.offset(woStatisticAnalysisReqVO.getStartDate(), DateField.MONTH, -1));
        statisticAnalysisReqVOMOM.setEndDate(DateUtil.offset(woStatisticAnalysisReqVO.getEndDate(), DateField.MONTH, -1));
        List<WoWorkOrder> sourceMOM = findSource(statisticAnalysisReqVOMOM); // 环比数据

        // 按照责任单位进行分组
        Map<String, List<WoWorkOrder>> groupWorkOrder = source.stream().collect(Collectors.groupingBy(WoWorkOrder
                ::getResponsibleUnit));
        List<WoThroughputResVO> woThroughputResVOList = new ArrayList<WoThroughputResVO>();
        List<SysOrg> sysOrgList = systemThirdService.getAllSysOrg();
        for (Map.Entry<String, List<WoWorkOrder>> map : groupWorkOrder.entrySet()) {
            WoThroughputResVO woThroughputResVO = new WoThroughputResVO();
            List<WoWorkOrder> woWorkOrderList = map.getValue();
            List<WoWorkOrder> woWorkOrderListYOY = sourceYOY.stream().filter(A -> A.getResponsibleUnit().equals(map.getKey())).collect(Collectors.toList());
            List<WoWorkOrder> woWorkOrderListMOM = sourceMOM.stream().filter(A -> A.getResponsibleUnit().equals(map.getKey())).collect(Collectors.toList());
            List<SysOrg> sysOrg = sysOrgList.stream().filter(A -> A.getId().equals(map.getKey())).collect(Collectors.toList());
            woThroughputResVO.setZrdw(CollUtil.isNotEmpty(sysOrg) ? sysOrg.get(0).getName() : ""); // 责任单位
            woThroughputResVO.setGdzs(woWorkOrderList.size()); // 工单数量
            woThroughputResVO.setZb12345gds((int) woWorkOrderList.stream()
                    .filter(A -> "05".equals(A.getInfoSerrces())).count()); // 来演于12315的单据数据
            woThroughputResVO.setPds(woWorkOrderList.size()); // 派单数（派单时间在这段时间内）
            woThroughputResVO.setPdsyoy(CalculateUtil.yoyCalculate(Double.valueOf(woWorkOrderListYOY.size()), Double.valueOf(woWorkOrderList.size()))); // 同比
            woThroughputResVO.setPdsmom((CalculateUtil.momCalculate(Double.valueOf(woWorkOrderListMOM.size()), Double.valueOf(woWorkOrderList.size())))); // 环比
            woThroughputResVO.setPdwcs((int) woWorkOrderList.stream()
                    .filter(A -> A.getDispatchTime() != null && A.getCompletionTime() != null).count()); // 派单完成数 派单时间不为空 & 完成时间不为空
            woThroughputResVO.setPdwcsyoy(CalculateUtil.yoyCalculate((double) woWorkOrderListYOY.stream()
                    .filter(A -> A.getDispatchTime() != null && A.getCompletionTime() != null).count(), Double.valueOf(woThroughputResVO.getPdwcs()))); // 同比
            woThroughputResVO.setPdwcsmom(CalculateUtil.momCalculate((double) woWorkOrderListMOM.stream()
                    .filter(A -> A.getDispatchTime() != null && A.getCompletionTime() != null).count(), Double.valueOf(woThroughputResVO.getPdwcs()))); // 环比
            woThroughputResVO.setHfcss((int) woWorkOrderList.stream()
                    .filter(A -> ((A.getFeedbackTime() != null && A.getFeedbackTime().getTime() > A.getExpirationTime().getTime())
                            || (A.getFeedbackTime() == null &&  new Date().getTime() > A.getExpirationTime().getTime())) ).count()); // 回复超时数
            woThroughputResVO.setJswcs((int) woWorkOrderList.stream()
                    .filter(A -> (ObjectUtils.allNotNull(A.getCompletionTime(), A.getExpirationTime()) && A.getCompletionTime()
                            .getTime() <= A.getExpirationTime().getTime())).count()); // 及时完成数
            woThroughputResVO.setZds((int) woWorkOrderList.stream().filter(A -> ("1".equals(A.getParentChild()))).count()); // 子单数
            woThroughputResVO.setMds((int) woWorkOrderList.stream().filter(A -> ("2".equals(A.getParentChild()))).count()); // 母单数
            woThroughputResVO.setTds((int) woWorkOrderList.stream()
                    .filter(A -> (ReplyTypeEnum.REPLY_CHARGEBACK.getCode().equals(A.getWorkOrderStatus()))).count()); // 退单数
            woThroughputResVO.setJgcbmy((int) woWorkOrderList.stream()
                    .filter(A -> ("2".equals(A.getProcessOpinion()) && !"2".equals(A.getResultOpinion()))).count()); // // 仅过程不满
            woThroughputResVO.setJjgbmy((int) woWorkOrderList.stream()
                    .filter(A -> (!"2".equals(A.getProcessOpinion()) && "2".equals(A.getResultOpinion()))).count());// 仅结果不满意
            woThroughputResVO.setJbmy((int) woWorkOrderList.stream()
                    .filter(A -> ("2".equals(A.getProcessOpinion()) && "2".equals(A.getResultOpinion()))).count());// 均不满意
            woThroughputResVO.setBds((int) woWorkOrderList.stream()
                    .filter(A -> (ConsStatusEnum.MAESTER.getCode().equals(A.getConsStatus()))).count());// 并单数量
            woThroughputResVO.setWbjs((int) woWorkOrderList.stream()
                    .filter(A -> (A.getDispatchTime() != null && A.getCompletionTime() == null)).count());// 未办结数
            woThroughputResVO.setBjs((int) woWorkOrderList.stream().filter(A -> (A.getCompletionTime() != null)).count());// 办结数
            woThroughputResVO.setCjl(CalculateUtil.ratioCalculate(woThroughputResVO.getBjs(), woThroughputResVO.getGdzs()));// 处结率
            // 处结率 同比  -  环比
            Double bjsYOYData = CalculateUtil.ratioCalculate((int) woWorkOrderListYOY.stream().filter(A -> (A.getCompletionTime() != null))
                    .count(), woWorkOrderListYOY.size());
            woThroughputResVO.setCjlyoy(CalculateUtil.yoyCalculate(bjsYOYData, woThroughputResVO.getCjl()));
            Double bjsMOMData = CalculateUtil.ratioCalculate((int) woWorkOrderListMOM.stream().filter(A -> (A.getCompletionTime() != null))
                    .count(), woWorkOrderListMOM.size());
            woThroughputResVO.setCjlmom(CalculateUtil.momCalculate(bjsMOMData, woThroughputResVO.getCjl()));
            // 处结及时率 同比  -  环比
            woThroughputResVO.setCjjsl(CalculateUtil.ratioCalculate(woThroughputResVO.getJswcs(), woThroughputResVO.getGdzs()));// 处结及时率
            Double cjjslYOYData = CalculateUtil.ratioCalculate((int) woWorkOrderListYOY.stream()
                    .filter(A -> (ObjectUtils.allNotNull(A.getCompletionTime(), A.getExpirationTime()) && A.getCompletionTime()
                            .getTime() <= A.getExpirationTime().getTime())).count(), woWorkOrderListYOY.size()); // 及时完成数
            woThroughputResVO.setCjjslyoy(CalculateUtil.yoyCalculate(cjjslYOYData, woThroughputResVO.getCjjsl()));
            Double cjjslMOMData = CalculateUtil.ratioCalculate((int) woWorkOrderListMOM.stream()
                    .filter(A -> (ObjectUtils.allNotNull(A.getCompletionTime(), A.getExpirationTime()) && A.getCompletionTime()
                            .getTime() <= A.getExpirationTime().getTime())).count(), woWorkOrderListMOM.size()); // 及时完成数
            woThroughputResVO.setCjjslmom(CalculateUtil.momCalculate(cjjslMOMData, woThroughputResVO.getCjjsl()));
            woThroughputResVO.setGdbl(CalculateUtil.ratioCalculate(woThroughputResVO.getGdzs(), source.size()));// 工单比例
            woThroughputResVOList.add(woThroughputResVO);
        }
        return AjaxResult.success(woThroughputResVOList);
    }

    /**
     * 工单统计 来源
     *
     * @param woStatisticAnalysisReqVO
     * @return
     */
    @Override
    public AjaxResult throughputSource(WoStatisticAnalysisReqVO woStatisticAnalysisReqVO) {
        woStatisticAnalysisReqVO.setDimension("dispatchTime");

        List<WoWorkOrder> source = findSource(woStatisticAnalysisReqVO); // 本期数据
        WoStatisticAnalysisReqVO statisticAnalysisReqVOYOY = BeanUtil.copyProperties(woStatisticAnalysisReqVO, WoStatisticAnalysisReqVO.class);
        statisticAnalysisReqVOYOY.setStartDate(DateUtil.offset(woStatisticAnalysisReqVO.getStartDate(), DateField.YEAR, -1));
        statisticAnalysisReqVOYOY.setEndDate(DateUtil.offset(woStatisticAnalysisReqVO.getEndDate(), DateField.YEAR, -1));
        List<WoWorkOrder> sourceYOY = findSource(statisticAnalysisReqVOYOY); // 同比数据
        WoStatisticAnalysisReqVO statisticAnalysisReqVOMOM = BeanUtil.copyProperties(woStatisticAnalysisReqVO, WoStatisticAnalysisReqVO.class);
        statisticAnalysisReqVOMOM.setStartDate(DateUtil.offset(woStatisticAnalysisReqVO.getStartDate(), DateField.MONTH, -1));
        statisticAnalysisReqVOMOM.setEndDate(DateUtil.offset(woStatisticAnalysisReqVO.getEndDate(), DateField.MONTH, -1));
        List<WoWorkOrder> sourceMOM = findSource(statisticAnalysisReqVOMOM); // 环比数据

        // 按照责任单位进行分组
        Map<String, List<WoWorkOrder>> groupWorkOrder = source.stream().collect(Collectors.groupingBy(WoWorkOrder
                ::getInfoSerrces));
        List<WoThroughputResVO> woThroughputResVOList = new ArrayList<WoThroughputResVO>();
        for (Map.Entry<String, List<WoWorkOrder>> map : groupWorkOrder.entrySet()) {
            WoThroughputResVO woThroughputResVO = new WoThroughputResVO();
            List<WoWorkOrder> woWorkOrderList = map.getValue();
            List<WoWorkOrder> woWorkOrderListYOY = sourceYOY.stream().filter(A -> A.getInfoSerrces().equals(map.getKey())).collect(Collectors.toList());
            List<WoWorkOrder> woWorkOrderListMOM = sourceMOM.stream().filter(A -> A.getInfoSerrces().equals(map.getKey())).collect(Collectors.toList());
            woThroughputResVO.setGdly(map.getKey());
            woThroughputResVO.setGdzs(woWorkOrderList.size()); // 工单数量
            woThroughputResVO.setPds(woWorkOrderList.size()); // 派单数（派单时间在这段时间内）
            woThroughputResVO.setPdsyoy(CalculateUtil.yoyCalculate(Double.valueOf(woWorkOrderListYOY.size()), Double.valueOf(woWorkOrderList.size()))); // 同比
            woThroughputResVO.setPdsmom((CalculateUtil.momCalculate(Double.valueOf(woWorkOrderListMOM.size()), Double.valueOf(woWorkOrderList.size())))); // 环比
            woThroughputResVO.setPdwcs((int) woWorkOrderList.stream()
                    .filter(A -> A.getDispatchTime() != null && A.getCompletionTime() != null).count()); // 派单完成数 派单时间不为空 & 完成时间不为空
            woThroughputResVO.setPdwcsyoy(CalculateUtil.yoyCalculate((double) woWorkOrderListYOY.stream()
                    .filter(A -> A.getDispatchTime() != null && A.getCompletionTime() != null).count(), Double.valueOf(woThroughputResVO.getPdwcs()))); // 同比
            woThroughputResVO.setPdwcsmom(CalculateUtil.momCalculate((double) woWorkOrderListMOM.stream()
                    .filter(A -> A.getDispatchTime() != null && A.getCompletionTime() != null).count(), Double.valueOf(woThroughputResVO.getPdwcs()))); // 环比
            woThroughputResVO.setHfcss((int) woWorkOrderList.stream()
                    .filter(A -> ((A.getFeedbackTime() != null && A.getFeedbackTime().getTime() > A.getExpirationTime().getTime())
                            || (A.getFeedbackTime() == null &&  new Date().getTime() > A.getExpirationTime().getTime())) ).count()); // 回复超时数
            woThroughputResVO.setJswcs((int) woWorkOrderList.stream()
                    .filter(A -> (ObjectUtils.allNotNull(A.getCompletionTime(), A.getExpirationTime()) && A.getCompletionTime()
                            .getTime() <= A.getExpirationTime().getTime())).count()); // 及时完成数
            woThroughputResVO.setZds((int) woWorkOrderList.stream().filter(A -> ("1".equals(A.getParentChild()))).count()); // 子单数
            woThroughputResVO.setMds((int) woWorkOrderList.stream().filter(A -> ("2".equals(A.getParentChild()))).count()); // 母单数
            woThroughputResVO.setTds((int) woWorkOrderList.stream()
                    .filter(A -> (ReplyTypeEnum.REPLY_CHARGEBACK.getCode().equals(A.getWorkOrderStatus()))).count()); // 退单数
            woThroughputResVO.setJgcbmy((int) woWorkOrderList.stream()
                    .filter(A -> ("2".equals(A.getProcessOpinion()) && !"2".equals(A.getResultOpinion()))).count()); // // 仅过程不满
            woThroughputResVO.setJjgbmy((int) woWorkOrderList.stream()
                    .filter(A -> (!"2".equals(A.getProcessOpinion()) && "2".equals(A.getResultOpinion()))).count());// 仅结果不满意
            woThroughputResVO.setJbmy((int) woWorkOrderList.stream()
                    .filter(A -> ("2".equals(A.getProcessOpinion()) && "2".equals(A.getResultOpinion()))).count());// 均不满意
            woThroughputResVO.setBds((int) woWorkOrderList.stream()
                    .filter(A -> (ConsStatusEnum.MAESTER.getCode().equals(A.getConsStatus()))).count());// 并单数量
            woThroughputResVO.setWbjs((int) woWorkOrderList.stream()
                    .filter(A -> (A.getDispatchTime() != null && A.getCompletionTime() == null)).count());// 未办结数
            woThroughputResVO.setBjs((int) woWorkOrderList.stream().filter(A -> (A.getCompletionTime() != null)).count());// 办结数
            woThroughputResVO.setCjl(CalculateUtil.ratioCalculate(woThroughputResVO.getBjs(), woThroughputResVO.getGdzs()));// 处结率
            // 处结率 同比  -  环比
            Double bjsYOYData = CalculateUtil.ratioCalculate((int) woWorkOrderListYOY.stream().filter(A -> (A.getCompletionTime() != null))
                    .count(), woWorkOrderListYOY.size());
            woThroughputResVO.setCjlyoy(CalculateUtil.yoyCalculate(bjsYOYData, woThroughputResVO.getCjl()));
            Double bjsMOMData = CalculateUtil.ratioCalculate((int) woWorkOrderListMOM.stream().filter(A -> (A.getCompletionTime() != null))
                    .count(), woWorkOrderListMOM.size());
            woThroughputResVO.setCjlmom(CalculateUtil.momCalculate(bjsMOMData, woThroughputResVO.getCjl()));
            // 处结及时率 同比  -  环比
            woThroughputResVO.setCjjsl(CalculateUtil.ratioCalculate(woThroughputResVO.getJswcs(), woThroughputResVO.getGdzs()));// 处结及时率
            Double cjjslYOYData = CalculateUtil.ratioCalculate((int) woWorkOrderListYOY.stream()
                    .filter(A -> (ObjectUtils.allNotNull(A.getCompletionTime(), A.getExpirationTime()) && A.getCompletionTime()
                            .getTime() <= A.getExpirationTime().getTime())).count(), woWorkOrderListYOY.size()); // 及时完成数
            woThroughputResVO.setCjjslyoy(CalculateUtil.yoyCalculate(cjjslYOYData, woThroughputResVO.getCjjsl()));
            Double cjjslMOMData = CalculateUtil.ratioCalculate((int) woWorkOrderListMOM.stream()
                    .filter(A -> (ObjectUtils.allNotNull(A.getCompletionTime(), A.getExpirationTime()) && A.getCompletionTime()
                            .getTime() <= A.getExpirationTime().getTime())).count(), woWorkOrderListMOM.size()); // 及时完成数
            woThroughputResVO.setCjjslmom(CalculateUtil.momCalculate(cjjslMOMData, woThroughputResVO.getCjjsl()));
            woThroughputResVO.setGdbl(CalculateUtil.ratioCalculate(woThroughputResVO.getGdzs(), source.size()));// 工单比例
            woThroughputResVOList.add(woThroughputResVO);
        }
        return AjaxResult.success(woThroughputResVOList);
    }

    /**
     * 工单满意度统计
     *
     * @param woStatisticAnalysisReqVO
     * @return
     */
    @Override
    public AjaxResult satisfaction(WoStatisticAnalysisReqVO woStatisticAnalysisReqVO) {
        woStatisticAnalysisReqVO.setDimension("acceptTime");
        List<WoWorkOrder> source = findSource(woStatisticAnalysisReqVO);
        // 按照责任单位进行分组 故障类别等工单的回访满意度统计分析。
        Map<String, List<WoWorkOrder>> groupWorkOrder = source.stream().collect(Collectors.groupingBy(item ->
                item.getResponsibleUnit() + "_" + item.getWorkOrderType()));
        List<WoSatisfactionResVO> woSatisfactionResVOList = new ArrayList<WoSatisfactionResVO>();
        for (Map.Entry<String, List<WoWorkOrder>> map : groupWorkOrder.entrySet()) {
            WoSatisfactionResVO woSatisfactionResVO = new WoSatisfactionResVO();
            List<WoWorkOrder> woWorkOrderList = map.getValue();
            woSatisfactionResVO.setZrdw(map.getKey().split("_")[0]); // 责任单位
            woSatisfactionResVO.setGdlx(map.getKey().split("_")[1]); // 类型
            woSatisfactionResVO.setGdzs(woWorkOrderList.size()); // 工单数量
            woSatisfactionResVO.setPds((int) woWorkOrderList.stream().filter(A -> A.getDispatchTime() != null).count()); // 派单数（派单时间在这段时间内）
            woSatisfactionResVO.setPdwcs((int) woWorkOrderList.stream()
                    .filter(A -> A.getDispatchTime() != null && A.getCompletionTime() != null).count()); // 派单完成数 派单时间不为空 & 完成时间不为空
            woSatisfactionResVO.setJgcbmy((int) woWorkOrderList.stream()
                    .filter(A -> ("2".equals(A.getProcessOpinion()) && !"2".equals(A.getResultOpinion()))).count()); // // 仅过程不满
            woSatisfactionResVO.setJjgbmy((int) woWorkOrderList.stream()
                    .filter(A -> (!"2".equals(A.getProcessOpinion()) && "2".equals(A.getResultOpinion()))).count());// 仅结果不满意
            woSatisfactionResVO.setJbmy((int) woWorkOrderList.stream()
                    .filter(A -> ("2".equals(A.getProcessOpinion()) && "2".equals(A.getResultOpinion()))).count());// 均不满意
            woSatisfactionResVO.setGdbl(CalculateUtil.ratioCalculate(woSatisfactionResVO.getGdzs(), source.size()));// 工单比例

            woSatisfactionResVOList.add(woSatisfactionResVO);
        }
        return AjaxResult.success(woSatisfactionResVOList);
    }

    /**
     * 工单量对比统计
     *
     * @param woStatisticAnalysisReqVO
     * @return
     */
    @Override
    public AjaxResult comparison(WoStatisticAnalysisReqVO woStatisticAnalysisReqVO) {
        woStatisticAnalysisReqVO.setDimension("acceptTime");

        List<WoWorkOrder> source = findSource(woStatisticAnalysisReqVO); // 本期数据
        WoStatisticAnalysisReqVO statisticAnalysisReqVOMOM = BeanUtil.copyProperties(woStatisticAnalysisReqVO, WoStatisticAnalysisReqVO.class);
        statisticAnalysisReqVOMOM.setStartDate(DateUtil.offset(woStatisticAnalysisReqVO.getStartDate(), DateField.MONTH, -1));
        statisticAnalysisReqVOMOM.setEndDate(DateUtil.offset(woStatisticAnalysisReqVO.getEndDate(), DateField.MONTH, -1));
        List<WoWorkOrder> sourceMOM = findSource(statisticAnalysisReqVOMOM); // 环比数据
        // 按照责任单位进行分组
        Map<String, List<WoWorkOrder>> groupWorkOrder = source.stream().collect(Collectors.groupingBy(WoWorkOrder
                ::getResponsibleUnit));
        List<WoComparisonResVO> woComparisonResVOList = new ArrayList<WoComparisonResVO>();
        for (Map.Entry<String, List<WoWorkOrder>> map : groupWorkOrder.entrySet()) {
            WoComparisonResVO woComparisonResVO = new WoComparisonResVO();
            List<WoWorkOrder> woWorkOrderList = map.getValue();
            List<WoWorkOrder> woWorkOrderListMOM = sourceMOM.stream().filter(A -> A.getResponsibleUnit().equals(map.getKey())).collect(Collectors.toList());

            woComparisonResVO.setZrdw(map.getKey()); // 责任单位
            woComparisonResVO.setGdzs(woWorkOrderList.size()); // 工单总数
            woComparisonResVO.setSqgdzs(woWorkOrderListMOM.size()); // 上期工单总数
            woComparisonResVO.setGdzshb(CalculateUtil.momCalculate(Double.valueOf(woWorkOrderListMOM.size()), Double.valueOf(woWorkOrderList.size()))); // 工单总数环比
            woComparisonResVO.setPdbjkh((int) woWorkOrderList.stream().filter(A -> A.getDispatchTime() != null && "1".equals(A.getDisergardKpi())).count()); // 派单不计考核数
            woComparisonResVO.setPds((int) woWorkOrderList.stream().filter(A -> A.getDispatchTime() != null).count()); // 派单数
            woComparisonResVO.setSqpds((int) woWorkOrderListMOM.stream().filter(A -> A.getDispatchTime() != null).count()); // 上期派单数
            woComparisonResVO.setPdshb(CalculateUtil.momCalculate(Double.valueOf(woComparisonResVO.getSqpds()), Double.valueOf(woComparisonResVO.getPds()))); // 派单数环比
            woComparisonResVO.setPdwcs((int) woWorkOrderList.stream().filter(A -> A.getDispatchTime() != null && A.getCompletionTime() != null).count()); // 派单完成数
            woComparisonResVO.setCjl(CalculateUtil.ratioCalculate((int) woWorkOrderList.stream().filter(A -> A.getCompletionTime() != null).count(), woWorkOrderList.size())); // 处结率
            woComparisonResVO.setJswcs((int) woWorkOrderList.stream()
                    .filter(A -> (ObjectUtils.allNotNull(A.getCompletionTime(), A.getExpirationTime()) && A.getCompletionTime()
                            .getTime() <= A.getExpirationTime().getTime())).count()); // 及时完成数
            woComparisonResVO.setJsl(CalculateUtil.ratioCalculate(woComparisonResVO.getJswcs(), woComparisonResVO.getGdzs()));// 处结及时率
            woComparisonResVO.setBds((int) woWorkOrderList.stream()
                    .filter(A -> (ConsStatusEnum.MAESTER.getCode().equals(A.getConsStatus()))).count());// 并单数量
            woComparisonResVOList.add(woComparisonResVO);

        }
        return AjaxResult.success(woComparisonResVOList);
    }

    /**
     * 在地图上展示工单分布情况
     *
     * @param woStatisticAnalysisReqVO
     * @return
     */
    @Override
    public AjaxResult distribute(WoStatisticAnalysisReqVO woStatisticAnalysisReqVO) {
        LambdaQueryWrapper<WoWorkOrder> queryWrapper = new QueryWrapper<WoWorkOrder>().lambda();
        queryWrapper.isNotNull(WoWorkOrder::getLatitude).isNotNull(WoWorkOrder::getLongitude)
                .ne(WoWorkOrder::getLatitude, "").ne(WoWorkOrder::getLongitude, "");
        // param == 行业类型
        if (CollUtil.isNotEmpty(woStatisticAnalysisReqVO.getIndustryTypes())) {
            queryWrapper.in(WoWorkOrder::getIndustryType, woStatisticAnalysisReqVO.getIndustryTypes());
        }
        // param == 责任单位
        if (CollUtil.isNotEmpty(woStatisticAnalysisReqVO.getResponsibleUnits())) {
            queryWrapper.in(WoWorkOrder::getResponsibleUnit, woStatisticAnalysisReqVO.getResponsibleUnits());
        }
        // param == 工单类型
        if (CollUtil.isNotEmpty(woStatisticAnalysisReqVO.getWorkOrderTypes())) {
            queryWrapper.in(WoWorkOrder::getWorkOrderType, woStatisticAnalysisReqVO.getWorkOrderTypes());
        }
        // 工单单号、12345单号、内容
        if (StringUtils.isNotBlank(woStatisticAnalysisReqVO.getSelectParam())) {
            queryWrapper.and(A -> A.like(WoWorkOrder::getWorkOrderNumber, woStatisticAnalysisReqVO.getSelectParam())
                    .or().like(WoWorkOrder::getExtOrderNumber, woStatisticAnalysisReqVO.getSelectParam())
                    .or().like(WoWorkOrder::getProblemDesc, woStatisticAnalysisReqVO.getSelectParam()));
        }
        // 并单
        queryWrapper.ne(WoWorkOrder::getConsStatus, ConsStatusEnum.SLAVE.getCode());
        return AjaxResult.success(woWorkOrderMapper.selectList(queryWrapper));
    }

    /**
     * 获取工单数据统计
     *
     * @return
     */
    @Override
    public AjaxResult getCount() {
        Map<String, Integer> result = new HashMap<>();
        // 获取当天的开始时间
        Date startDate = DateUtil.beginOfDay(new Date());
        // 获取当天的结束时间
        Date endDate = DateUtil.endOfDay(new Date());

        // 今日工单量
        Integer todayNum = woWorkOrderMapper.selectCount(new QueryWrapper<WoWorkOrder>().lambda().between(WoWorkOrder::getAcceptTime, startDate, endDate));
        result.put("todayNum", todayNum);
        // 今日结单量
        Integer colseNum = woWorkOrderMapper.selectCount(new QueryWrapper<WoWorkOrder>().lambda().between(WoWorkOrder::getCompletionTime, startDate, endDate));
        result.put("colseNum", colseNum);

        // 延期工单量
        Integer extensionNum = woExtensionMapper.selectCount(new QueryWrapper<WoExtension>().lambda().between(WoExtension::getFilledTime, startDate, endDate));
        result.put("extensionNum", extensionNum);

        // 投诉工单量
        Integer complainNum = woWorkOrderMapper.selectCount(new QueryWrapper<WoWorkOrder>().lambda()
                .between(WoWorkOrder::getAcceptTime, startDate, endDate).eq(WoWorkOrder::getWorkOrderType, "02"));
        result.put("complainNum", complainNum);

        // 督办工单量
        Integer superviseNum = woSuperviseMapper.selectCount(new QueryWrapper<WoSupervise>().lambda().between(WoSupervise::getFilledTime, startDate, endDate));
        result.put("superviseNum", superviseNum);


        // 不计考核工单量
        Integer disregardNum = woDisregardKpiMapper.selectCount(new QueryWrapper<WoDisregardKpi>().lambda().between(WoDisregardKpi::getFilledTime, startDate, endDate));
        result.put("disregardNum", disregardNum);


        return AjaxResult.success(result);
    }

    /**
     * 通过各类插叙条件获取将要被统计的工单数据
     *
     * @param woStatisticAnalysisReqVO
     * @return
     */
    private List<WoWorkOrder> findSource(WoStatisticAnalysisReqVO woStatisticAnalysisReqVO) {
        // ① 按照各类查询条件获取工单数据
        LambdaQueryWrapper<WoWorkOrder> queryWrapper = new QueryWrapper<WoWorkOrder>().lambda();
        // param == 受理时间
        if (ObjectUtils.allNotNull(woStatisticAnalysisReqVO.getStartDate(), woStatisticAnalysisReqVO.getEndDate()) &&
                woStatisticAnalysisReqVO.getDimension().equals("dispatchTime")) {
            queryWrapper.ge(WoWorkOrder::getDispatchTime, woStatisticAnalysisReqVO.getStartDate());
            queryWrapper.le(WoWorkOrder::getDispatchTime, woStatisticAnalysisReqVO.getEndDate());
        }
        if (ObjectUtils.allNotNull(woStatisticAnalysisReqVO.getStartDate(), woStatisticAnalysisReqVO.getEndDate()) &&
                woStatisticAnalysisReqVO.getDimension().equals("acceptTime")) {
            queryWrapper.ge(WoWorkOrder::getAcceptTime, woStatisticAnalysisReqVO.getStartDate());
            queryWrapper.le(WoWorkOrder::getAcceptTime, woStatisticAnalysisReqVO.getEndDate());
        }
        // param == 行业类型
        if (CollUtil.isNotEmpty(woStatisticAnalysisReqVO.getIndustryTypes())) {
            queryWrapper.in(WoWorkOrder::getIndustryType, woStatisticAnalysisReqVO.getIndustryTypes());
        }
        // param == 责任单位
        if (CollUtil.isNotEmpty(woStatisticAnalysisReqVO.getResponsibleUnits())) {
            queryWrapper.in(WoWorkOrder::getResponsibleUnit, woStatisticAnalysisReqVO.getResponsibleUnits());
        }
        // param == 工单类型
        if (CollUtil.isNotEmpty(woStatisticAnalysisReqVO.getWorkOrderTypes())) {
            queryWrapper.in(WoWorkOrder::getWorkOrderType, woStatisticAnalysisReqVO.getWorkOrderTypes());
        }
        // 并单
        queryWrapper.ne(WoWorkOrder::getConsStatus, ConsStatusEnum.SLAVE.getCode());
        // 符合条件的工单数据
        return woWorkOrderMapper.selectList(queryWrapper);
    }
}
